/*********************************************************************************
 * Software License Agreement (BSD License)
 * Copyright (c) 2012, Carlos D. Correa (info@ngraph.org)
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of netzen nor the
 *    names of its contributors may be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *********************************************************************************/
#include "glheaders.h"
#include "shortcut.h"
#include "controller.h"
#include "view.h"
#include "graph.h"
#include <assert.h>
#include <math.h>

#include <string>
using namespace std;
class GridShortcut:public Shortcut {
public:
  GridShortcut(string name): Shortcut(name) {
  };
  virtual void run() {
	  assert(controller);
		vector<ViewInfo> info = controller->getViews();
		vector<View*> visibleFrames;
    for(unsigned int i = 0; i < info.size(); i++) {
			string name = info[i].name;
			string type = info[i].type;
			View *view = controller->getView(name);
			assert(view);
			if(view->isVisible()) {
				visibleFrames.push_back(view);
			}
		}
			
		unsigned int N = visibleFrames.size();
		float sqr = sqrt((float) N);
		unsigned int gridx = (int) sqr;
		unsigned int gridy = gridx;
		while(gridx*gridy<N) {
			gridy++;
		}
    for(unsigned int i = 0; i < visibleFrames.size(); i++) {
			View *view = visibleFrames[i];
			assert(view);
			float x = (float) (i%gridx)/(float) gridx;
			float y = (float) ((int)(i/gridx))/(float) gridy;
			float w = 2.0/(float) gridx;
			float h = 2.0/(float) gridy;
			view->setLocation(2.0*x-1.0,1.0-2.0*y);
			view->setSize(w,h);
		}			
		controller->updateRender();
	}
};


class LayeredShortcut:public Shortcut {
public:
  LayeredShortcut(string name): Shortcut(name) {
  };
  virtual void run() {
	  assert(controller);
		vector<ViewInfo> info = controller->getViews();
		vector<View*> visibleFrames;
    for(unsigned int i = 0; i < info.size(); i++) {
			string name = info[i].name;
			string type = info[i].type;
			View *view = controller->getView(name);
			assert(view);
			if(view->isVisible()) {
				visibleFrames.push_back(view);
			}
		}
		
		unsigned int N = visibleFrames.size();
		float sqr = sqrt((float) N);
		float minw = 1.6;
		float minh = 1.2;
		float dx = (2.0 - minw)/(float) (N-1);
		float dy = (2.0 - minh)/(float) (N-1);
    for(unsigned int i = 0; i < visibleFrames.size(); i++) {
			View *view = visibleFrames[i];
			assert(view);
			float x = -1.0 + ((float) i) * dx;
			float y = 1.0 - ((float) i) * dy;
			float w = minw;
			float h = minh;
			view->setLocation(x, y);
			view->setSize(w,h);
		}			
		controller->updateRender();
	}
};

class ToggleTransparent:public Shortcut {
	bool transparent;
public:
  ToggleTransparent(string name): Shortcut(name) {
		transparent = true;
  };
  virtual void run() {
	  assert(controller);
		vector<ViewInfo> info = controller->getViews();
    for(unsigned int i = 0; i < info.size(); i++) {
			string name = info[i].name;
			string type = info[i].type;
			View *view = controller->getView(name);
			assert(view);
			if(view->isVisible()) {
				view->setPropertyBool("View.transparent", transparent);
			}
		}
		transparent = !transparent;
		controller->updateRender();
	}
};

void createCanvasShortcuts(Controller *controller) {
	controller->addShortcut(new GridShortcut("Canvas/GridLayout"));
	controller->addShortcut(new LayeredShortcut("Canvas/LayeredShortcut"));
	controller->addShortcut(new ToggleTransparent("Canvas/ToggleTransparent"));
	//controller->addShortcut(createDummyShortcut("Canvas/MakeTransparent"));
	//controller->addShortcut(createDummyShortcut("Canvas/Snapshot"));
	
}
